﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormsSimpleCrawler
{
    public partial class Form1 : Form
    {
        Crawler myCrawler = new Crawler();


        public Form1()
        {
            InitializeComponent();
            dataGridView1.DataSource = bindingSource1;//数据绑定
            myCrawler.PageDownloaded += Crawler_PageDownloaded;//事件绑定
            myCrawler.CrawlerStopped += Crawler_CrawlerStopped;//事件绑定

        }
        private void Crawler_CrawlerStopped(Crawler obj)
        {
            Action action = () => label2.Text = "爬虫已停止";
            //Windows 窗体中的控件被绑定到特定的线程，不具备线程安全性 。因此，如果从另一个线程调用控件的方法，
            //那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法，
            //当不知道什么线程拥有控件时这很有用。
            if (this.InvokeRequired)
            {
                this.Invoke(action);
            }
            else
            {
                action();
            }
            
        }

        private void Crawler_PageDownloaded(Crawler crawler, string url, string info)
        {
            var pageInfo = new { Index = bindingSource1.Count + 1, URL = url, Status = info };
            Action action = () => { bindingSource1.Add(pageInfo); };
            if (this.InvokeRequired)
            {
                this.Invoke(action);
            }
            else
            {
                action();
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        { 

            bindingSource1.Clear();
            myCrawler.startURL = textBox1.Text;//获取起始地址

            Match match = Regex.Match(myCrawler.startURL, Crawler.urlParseRegex);
            if (match.Length == 0) return;
            string host = match.Groups["host"].Value;
            myCrawler.HostFilter = "^" + host + "$";
            myCrawler.FileFilter = ".html?$";
            //Task 是基于 Thread 的，是比较高层级的封装， Task 最终还是需要 Thread 来执行
            //2、 Task 默认使用后台线程执行， Thread 默认使用前台线程
            new Thread(myCrawler.Crawl).Start();//开始爬行
            //Task task = Task.Run(() => myCrawler.Crawl());//开始爬行
            label2.Text = "爬虫已启动";

        }
    }
}
